package com.oim.core.common.component;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import org.apache.commons.io.FilenameUtils;

import com.oim.core.common.component.file.FileAction;
import com.oim.core.common.util.FileNameUtil;
import com.only.common.util.OnlyFileUtil;
import com.only.common.util.OnlyMD5Util;
import com.only.common.util.OnlyNumberUtil;

/**
 * @author: XiaHui
 * @date: 2017年4月20日 上午10:07:09
 */
public class FileHttpDownload {

	public void download(String http, String savaPath, String fileName, FileAction<File> fileAction) {
		download(http, savaPath, fileName, false, fileAction);
	}

	public void download(String http, String savaPath, String fileName, boolean onlyReplaceName, FileAction<File> fileAction) {
		download(http, "POST", savaPath, fileName, false, fileAction);
	}

	public void download(String http, String method, String savaPath, String fileName, boolean onlyReplaceName, FileAction<File> fileAction) {
		boolean success = true;
		try {
			URL url = new URL(http);// 统一资源
			URLConnection urlConnection = url.openConnection();// 连接类的父类，抽象类
			HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;// http的连接类
			if ("POST".equals(method) || "GET".equals(method)) {
				httpURLConnection.setRequestMethod(method);// 设定请求的方法，默认是GET
			}
			httpURLConnection.setRequestProperty("Charset", "UTF-8");// 设置字符编码
			httpURLConnection.connect();// 打开到此 URL 引用的资源的通信链接（如果尚未建立这样的连接）。

			String disposition = httpURLConnection.getHeaderField("Content-Disposition");
			String tempName = getFileNameFromUrl(http);
			String dispositionName = null;
			if (null != disposition && !"".equals(disposition)) {
				String[] array = disposition.split("filename=");
				if (array.length > 1) {
					dispositionName = array[1];
				}
			}
			String saveName = fileName;

			if (onlyReplaceName) {// 如果只是替换原文件的名称，不包含后缀名
				if (null != fileName && !"".equals(fileName)) {
					if (null != dispositionName && !"".equals(dispositionName)) {// 如果原文件名不为空
						String name = FileNameUtil.getName(fileName);
						String suffixName = FileNameUtil.getSuffixName(dispositionName);
						if (null == suffixName || "".equals(suffixName)) {
							saveName = fileName;
						} else {
							saveName = name + "." + suffixName;
						}
					} else if (null != tempName && !"".equals(tempName)) {
						String name = FileNameUtil.getName(fileName);
						String suffixName = FileNameUtil.getSuffixName(tempName);
						if (null == suffixName || "".equals(suffixName)) {
							saveName = fileName;
						} else {
							saveName = name + "." + suffixName;
						}
					} else {
						saveName = fileName;
					}

				} else {
					if (null != dispositionName && !"".equals(dispositionName)) {// 如果原文件名不为空
						saveName = dispositionName;
					} else if (null != tempName && !"".equals(tempName)) {
						saveName = tempName;
					} else {
						saveName = FileNameUtil.getSaveName("");
					}
				}

			} else {
				if (null != fileName && !"".equals(fileName)) {

				} else {
					if (null != dispositionName && !"".equals(dispositionName)) {// 如果原文件名不为空
						saveName = dispositionName;
					} else if (null != tempName && !"".equals(tempName)) {
						saveName = tempName;
					} else {
						saveName = FileNameUtil.getSaveName("");
					}
				}
			}

			BufferedInputStream in = new BufferedInputStream(httpURLConnection.getInputStream());

			String fileFullName = savaPath + saveName;
			int size = httpURLConnection.getContentLength();// 文件大小

			OnlyFileUtil.createParentFolder(fileFullName);

			File file = new File(fileFullName);
			OutputStream out = new FileOutputStream(file);
			byte[] buf = new byte[1024];

			int length = 0;
			long speed = 0;
			long up = 0;
			long time = System.currentTimeMillis();
			while ((length = in.read(buf)) != -1) {
				out.write(buf, 0, length);
				speed = speed + length;
				up = up + length;
				long tempTime = System.currentTimeMillis();
				if (tempTime - time > 1000 && null != fileAction) {
					double percentage = (up > 0 && size > 0) ? ((double) up / (double) size) : 1d;
					fileAction.progress(speed, size, up, percentage);
					speed = 0;
					time = tempTime;
				}
			}
			in.close();
			out.close();
			if (null != fileAction) {
				double percentage = (up > 0 && size > 0) ? ((double) up / (double) size) : 1d;
				fileAction.progress(speed, size, up, percentage);
				fileAction.success(file);
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
			success = false;
		} catch (IOException e) {
			e.printStackTrace();
			success = false;
		}
		if (!success && null != fileAction) {
			if (null != fileAction) {
				fileAction.lost(null);
			}
		}
	}

	public static String getFileNameFromUrl(String url) {
		if (url == null) {
			return null;
		}

		try {
			// Add a protocol if none found
			if (!url.contains("//")) {
				url = "http://" + url;
			}
			URL uri = new URL(url);
			String result = FilenameUtils.getName(uri.getPath());

			if (result == null || result.isEmpty()) {
				return null;
			}
			if (result.contains("..")) {
				return null;
			}
			return result;
		} catch (MalformedURLException e) {
			return null;
		}
	}

	public void download(String http, File saveFile, FileAction<File> fileAction) {
		try {
			URL url = new URL(http);// 统一资源
			URLConnection urlConnection = url.openConnection();// 连接类的父类，抽象类
			HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;// http的连接类
			httpURLConnection.setRequestMethod("POST");// 设定请求的方法，默认是GET
			httpURLConnection.setRequestProperty("Charset", "UTF-8");// 设置字符编码
			httpURLConnection.connect();// 打开到此 URL 引用的资源的通信链接（如果尚未建立这样的连接）。

			String absolutePath = saveFile.getAbsolutePath();
			// String name = saveFile.getName();

			int size = httpURLConnection.getContentLength();// 文件大小
			BufferedInputStream in = new BufferedInputStream(httpURLConnection.getInputStream());

			OnlyFileUtil.createParentFolder(absolutePath);
			// FileInfo fd = new FileInfo();
			// fd.setName(name);
			OutputStream out = new FileOutputStream(saveFile);
			byte[] buf = new byte[1024];

			int length = 0;
			long speed = 0;
			long up = 0;
			long time = System.currentTimeMillis();
			while ((length = in.read(buf)) != -1) {
				out.write(buf, 0, length);
				speed = speed + length;
				up = up + length;
				long tempTime = System.currentTimeMillis();
				if (tempTime - time > 1000 && null != fileAction) {
					double percentage = (up > 0 && size > 0) ? ((double) up / (double) size) : 1d;
					fileAction.progress(speed, size, up, percentage);
					speed = 0;
					time = tempTime;
				}
			}
			in.close();
			out.close();
			if (null != fileAction) {
				double percentage = (up > 0 && size > 0) ? ((double) up / (double) size) : 1d;
				fileAction.progress(speed, size, up, percentage);
				// fd.setFile(saveFile);
				// fd.setSize(saveFile.length());
				fileAction.success(saveFile);
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
			if (null != fileAction) {
				fileAction.lost(saveFile);
			}
		} catch (IOException e) {
			e.printStackTrace();
			if (null != fileAction) {
				fileAction.lost(saveFile);
			}
		}
	}

	public static void main(String[] arg) {
		FileAction<File> fileAction = new FileAction<File>() {

			@Override
			public void progress(long speed, long size, long finishSize, double percentage) {

				String speedText = "0MB/s";
				if (speed < 1024) {
					speedText = speed + "B/s";
				} else if (1024 <= speed && speed < (1024 * 1024)) {
					String s = OnlyNumberUtil.format(((double) speed / 1024d));
					speedText = s + "KB/s";
				} else {
					String s = OnlyNumberUtil.format(((double) speed / (double) (1024 * 1024)));
					speedText = s + "MB/s";
				}

				System.out.println("size:" + size);
				System.out.println("finishSize:" + finishSize);
				System.out.println("percentage:" + percentage);
				System.out.println(speedText);
				System.out.println("");
			}

			@Override
			public void success(File fileData) {
				// System.out.println("success id=" + fileData.getId());
				// System.out.println("success size=" + fileData.getSize());
			}

			@Override
			public void lost(File file) {

			}

		};
		String http = "http://static.oschina.net/uploads/img/201602/18224123_YSM6.jpg";
		File file = new File(http);
		System.out.println("file:" + file.getName());
		// System.out.println(file.exists());
		//
		// File newFile = new
		// File("E:/Temp/Download/6dd79b2f-3233-453e-b414-944819996818.jpg");
		// System.out.println("newFile:"+newFile.getAbsolutePath());

		String md5 = OnlyMD5Util.md5L32(http);
		// String http =
		// "http://127.0.0.1:8020/oim-file-server/file/download.do?id=6dd79b2f-3233-453e-b414-944819996818";
		FileHttpDownload fhd = new FileHttpDownload();
		fhd.download(http, "GET","E:/Temp/Download/", md5, true, fileAction);
	}
}
